﻿'// ========================================================================= '
'// ------------------------------------------------------------------------- '
'//!				\file		CM_Table.vb
'			        \date		june 2010
'			        \author		TNick
'
'			        \brief		
'
'
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'   This file is considered universal knowledge. No restrictions
'   are imposed; use as you see fit.
'   Please read ReadMe.txt and Licence.txt in root folder
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'
'
'// ------------------------------------------------------------------------- '
'// ========================================================================= '
'//
'//
'//
'//
'//  IMPORTS     ------------------------------------------------------------ '
#Region "Imports"

Imports System
Imports Microsoft.Win32

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Customization

Imports FSK_XL

#End Region
'//  IMPORTS     ============================================================ '
'//
'//
'//
'//
'//  DEFINITIONS    --------------------------------------------------------- '
<Assembly: CommandClass(GetType(CM_Table))> 


#Region "Public Structures"
    

    '// --------------------------------------------------------------------- '
    '// defines the settings for creating a grid
    Public Structure TBLSTG
        Dim sExclImp As String
        Dim bImpTx As Boolean
    End Structure
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// specifies all informations regarding a table's layout that needs 
    '// to be inserted
    Public Structure TBLLY
        Dim lyData As XLS.LAY
        Dim dScale As Double
        Dim dNorth As Double
        Dim dEast As Double
        Dim sTxSty As String
        Dim bImpTx As Boolean
        '// hjolds the text content of the cells
        Dim sTxCnt() As String

    End Structure
    '// ===================================================================== '

#End Region


'//  DEFINITIONS    ========================================================= '
'//
'//
'//
'//
'//  DATA    ---------------------------------------------------------------- '


'//  DATA    ================================================================ '
'//
'//
'//
'//
'//  CLASS    --------------------------------------------------------------- '
Public Class CM_Table
	Inherits CModule


    '// --------------------------------------------------------------------- '
    '// DATA

    #Region "Public Constants"
        '// name as displayed in various places
	    Public Const sAPPNAME As String = "Tables"
        '// version as displayed in various places
	    Public Const sAPPVER As String = "1.0.0.0"
        '// short description
	    Public sAPPTIP As String

        '// Command. Brings up the settings dialog
        Public Const sCMD_SETTINGS As String = "TNIK_TBL_STG"
        '// Command. Import a layout using command line
        Public Const sCMD_FROMEXCEL As String = "TNIK_TBL_XL"
        '// Command. Import a layout using GUI
        Public Const sCMD_FROMEXCELGUI As String = "TNIK_TBL_XLG"
    #End Region

    '// this is where the settings are stored durring run-time
    Public Shared Stgs As TBLSTG

    '// ===================================================================== '






#Region "Private general purpose Functions"


    '// --------------------------------------------------------------------- '
	'// This function saves current settings
	Private Shared Sub SaveSett()
		CSett.SaveStg(sAPPNAME, "Stgs.sExclImp", CStr(Stgs.sExclImp))

	End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
	'// This function loads current settings
	Private Shared Sub GetSett()
		Stgs.sExclImp = CSett.GetStrStg(sAPPNAME, "Stgs.sExclImp", "")
	End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
	'// This function shows current settings
	Private Shared Function PrintStg(ByRef lcStg As CRJSTG) As String
        'Return (vbCrLf & CMain._T(TX.CSTG) & sAPPNAME & ": " & vbCrLf & _
		'  CMain._T(TX.CROSS) & " = " & CStr(lcStg.IN_mrk) & vbCrLf & _
		'  vbTab & CMain._T(TX.VALUES)  & " = " & CStr(lcStg.IN_txt) & vbCrLf & _
		'  vbTab & CMain._T(TX.HTEXT)  & " = " & Format(lcStg.IN_txh, "0.000") & vbCrLf & _
		'  vbTab & CMain._T(TX.HLINE)  & " = " & Format(lcStg.IN_csz, "0.000") & vbCrLf & _
		'  vbTab & CMain._T(TX.SPAN) & " = " & Format(lcStg.IN_dst, "0.000") & vbCrLf & _
		'  CMain._T(TX.BORDER) & " = " & CStr(lcStg.BR_mrk) & vbCrLf & _
		'  vbTab & CMain._T(TX.VALUES) &  " = " & CStr(lcStg.BR_txt) & vbCrLf & _
		'  vbTab & CMain._T(TX.HTEXT) &  " = " & Format(lcStg.BR_txh, "0.000") & vbCrLf & _
		'  vbTab & CMain._T(TX.HLINE) &  " = " & Format(lcStg.BR_csz, "0.000") & vbCrLf & _
		'  vbTab & CMain._T(TX.SPAN) & " = " & Format(lcStg.BR_dst, "0.000") & vbCrLf & vbCrLf _
		'  )
        Return Nothing
	End Function
    '// ===================================================================== '

#End Region


#Region "Common interface" ' -----------------------

    '// --------------------------------------------------------------------- '
	'// a new instance is created
	Public Sub New()
		Try
            sAPPTIP = CMain._T(TX.DIM_INFO)
			Return
		Catch ex As System.Exception
			CMain.DebugException(ex)
			Return
		End Try
	End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// the module is asked to terminate
	Public Overrides Function Terminate() As Boolean
		Try
			SaveSett()
			Return True
		Catch ex As System.Exception
			CMain.DebugException(ex)
			Return False
		End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
	End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// the module is asked to tell it's name
	Public Shared Function GetName() As String
		Return sAPPNAME
	End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// the module is asked to tell about itself
	Public Shared Sub GetInfos(ByRef sName As String, ByRef sVer As String, ByRef sTip As String)
		sName = sAPPNAME
		sVer = sAPPVER
		sTip = CMain._T(TX.DIM_INFO)
	End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// the module is asked to tell about itself
	Public Shared Function GetDescription() As String
        Dim sOut As String = sAPPNAME
        Try
            Dim cIni As New IniWork(CApp.sAppPath & CMain.APPSTG)
            If cIni.HasErrors = True Then Exit Try
            sOut = cIni.Read(sAPPNAME, CMain.DESCRKEY & _
                             CMain.eAppLang.ToString,sAPPNAME)
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
        Return sOut
	End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// the module is informed about application start-up
	Public Shared Sub DoPrereq()
		Try
			' this function is called at application start-up in order to 
			' allow applications to do any prerequisites
			' there is no instance of this class at this time
			GetSett()
		Catch ex As System.Exception
			CMain.DebugException(ex)
		End Try
		Return
	End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// create the user interface for this module
	Public Shared Sub DoCUI( _
	 ByRef pcs As CustomizationSection, _
	 ByRef mg As MacroGroup)
		' this function is called when a CUI is builded in order to
		' allow any application specifics
		Try
        #If HARDCORE_CUI
            If CApp.cuiCl Is Nothing then Exit Try
            CApp.cuiCl.AddMacro(sCMD_FROMEXCEL,"TBL_Excel")
            CApp.cuiCl.AddMacro(sCMD_FROMEXCELGUI,"TBL_ExcelGui")
            CApp.cuiCl.AddMacro(sCMD_SETTINGS,"TBL_Settings")

            CApp.cuiCl.AddToolbar( _
                sAPPNAME, _
                Application.MainWindow.Location.X, _
                100 + MIDS.TABLE * 30)
            CApp.cuiCl.AddToolbarBtn(CMain._T(tx.IMPORT),sCMD_FROMEXCEL)
            CApp.cuiCl.AddToolbarBtn(CMain._T(tx.IMPORT),sCMD_FROMEXCELGUI)
            CApp.cuiCl.AddToolbarBtn(CMain._T(tx.SETTINGS),sCMD_SETTINGS)

        #Else

			Dim mm1 As MenuMacro = Nothing
			mm1 = New MenuMacro(mg, sCMD_FROMEXCEL, "^C^C" & sCMD_FROMEXCEL, "ID_" & sCMD_FROMEXCEL)
			mm1 = New MenuMacro(mg, sCMD_SETTINGS, "^C^C" & sCMD_SETTINGS, "ID_" & sCMD_SETTINGS)


			Dim tbBtn As ToolbarButton = Nothing
			Dim newTb As Toolbar = New Toolbar(sAPPNAME, pcs.MenuGroup)
			newTb.ElementID = "EID_TNIK_Table"
			newTb.ToolbarOrient = ToolbarOrient.floating
			newTb.ToolbarVisible = ToolbarVisible.show
            newTb.XCoordinate = Application.MainWindow.Location.X
            newTb.YCoordinate = 100 + MIDS.TABLE * 30

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.CRTBLLAY)
			tbBtn.MacroID = "ID_" & sCMD_FROMEXCEL

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.CRTBLLAYG)
			tbBtn.MacroID = "ID_" & sCMD_FROMEXCELGUI

			tbBtn = New ToolbarButton(newTb, -1) ' separator

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.SETTINGS)
			tbBtn.MacroID = "ID_" & sCMD_SETTINGS
        #End If

		Catch ex As System.Exception
			CMain.DebugException(ex)
		End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
	End Sub
    '// ===================================================================== '


#End Region

#Region "Internal base work"


#End Region


#Region "Public functions"

    Public Shared Function GetAlgn(ByVal inp as XLS.ALGN) As CellAlignment

        Select Case inp
        Case    XLS.ALGN.TOPLEFT
            Return CellAlignment.TopLeft
        Case    XLS.ALGN.TOPCENTER   
            Return CellAlignment.TopCenter
        Case    XLS.ALGN.TOPRIGHT
            Return CellAlignment.TopRight
        Case    XLS.ALGN.MIDDLELEFT
            Return CellAlignment.MiddleLeft
        Case    XLS.ALGN.MIDDLECENTER
            Return CellAlignment.MiddleCenter
        Case    XLS.ALGN.MIDDLERIGHT
            Return CellAlignment.MiddleRight
        Case    XLS.ALGN.BTMLEFT
            Return CellAlignment.BottomLeft
        Case    XLS.ALGN.BTMCENTER
            Return CellAlignment.BottomCenter
        Case    else '    XLS.ALGN.BTMRIGHT
            Return CellAlignment.BottomRight
        End Select

    End Function


    '// --------------------------------------------------------------------- '
	'// create a table based on a layout
    Public Shared Function CreateTblFromLay(ByRef acDoc As Document, _
                                     ByRef tLy As TBLLY) As Boolean

', _
'                                     ByRef xlSheet As XLS

        Using acTrans As Transaction = _
            acDoc.Database.TransactionManager.StartTransaction()
		Try
            Dim acBlkTblRec As BlockTableRecord = DirectCast( _
                    acTrans.GetObject(acDoc.Database.CurrentSpaceId, _
                                        OpenMode.ForWrite), _
                    BlockTableRecord)
            
            Dim acTbl As new Table
            acTbl.SetDatabaseDefaults()
            acTbl.IsHeaderSuppressed = True
            acTbl.IsTitleSuppressed = True
            acTbl.NumRows = tLy.lyData.iRowCnt
            acTbl.NumColumns = tLy.lyData.iColCnr
            acTbl.Position = new Point3d(tLy.dEast, tLy.dNorth, 0)
            Dim i As Integer = 0
            '// create the table with this layout
            For c As Integer = 0 to tLy.lyData.iColCnr-1
                For r As Integer =  0 to tLy.lyData.iRowCnt-1
                    If (tLy.lyData.cLay(i) <> XLS.LAYCELL.MERGED) Then
                        acTbl.SetTextHeight(r, c, tLy.lyData.dTxH(i))
                        'acTbl.SetTextString(r, c, )
                        acTbl.SetAlignment(r, c, GetAlgn(tLy.lyData.aAlgn(i)))
                    End if
                Next
                acTbl.SetColumnWidth(tLy.dScale * tLy.lyData.dWidths(c))
            Next
            For r As Integer =  0 to tLy.lyData.iRowCnt-1
                acTbl.SetRowHeight(tLy.dScale * tLy.lyData.dHeights(r))
            Next
            For i = 0 to UBound(tLy.lyData.aMrg)
                Dim Cellreg As TableRegion = _
                    New TableRegion( _
                        tLy.lyData.aMrg(i).r1-1, _
                        tLy.lyData.aMrg(i).c1-1, _
                        tLy.lyData.aMrg(i).r2-1, _
                        tLy.lyData.aMrg(i).c2-1)
                acTbl.MergeCells(Cellreg)
            Next
            If tLy.bImpTx And (tLy.sTxCnt IsNot Nothing) Then
                Dim sTx As String
                For c As Integer = 0 to tLy.lyData.iColCnr-1
                    For r As Integer =  0 to tLy.lyData.iRowCnt-1
                        If (tLy.lyData.cLay(i) <> XLS.LAYCELL.MERGED) Then
                            sTx = tLy.sTxCnt(r*tLy.lyData.iColCnr + c)
                            Call acTbl.SetTextString(r, c, sTx)
                        End if
                    Next
                Next
            End If

            acBlkTblRec.AppendEntity(acTbl)
            acTrans.AddNewlyCreatedDBObject(acTbl, true)
            acTrans.Commit()
		Catch ex As System.Exception
            acTrans.Abort()
			CMain.DebugException(ex)
            CMain.PopUpExc()
		End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
        End Using

    End Function
    '// ===================================================================== '
    
#End Region


#Region "C O M M A N D S"


    '// --------------------------------------------------------------------- '
	'// display settings dialog
	<CommandMethod(sCMD_SETTINGS)> _
	Public Sub Show_Settings()
		Try
            Dim StgD As CST_Tabel = New CST_Tabel
            Application.ShowModelessDialog(StgD)
		Catch ex As System.Exception
			CMain.DebugException(ex)
            CMain.PopUpExc()
		End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
	End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// GUI for layout import
	<CommandMethod(sCMD_FROMEXCELGUI)> _
	Public Sub ImpLayFromExcelGui()
		Try
            Dim StgD As CD_ImpLay = New CD_ImpLay
            Application.ShowModelessDialog(StgD)
		Catch ex As System.Exception
			CMain.DebugException(ex)
            CMain.PopUpExc()
		End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
	End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
	'// Create table from excel sheet
	<CommandMethod(sCMD_FROMEXCEL)> _
	Public Sub ImpLayFromExcel()
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        If (acDoc Is Nothing) Then Return

        Dim acPoly As Polyline = Nothing
	    Dim db As Database = acDoc.Database
	    Dim ed As Editor = acDoc.Editor
        Dim ExcelSheet As XLS = Nothing
        Dim ExcelWorkbook As XLW = Nothing
        Dim tLy As TBLLY = Nothing


        tLy.lyData.iRowStart = 1
        tLy.lyData.iColStart = 1
        tLy.lyData.iRowCnt = 10
        tLy.lyData.iColCnr = 10
        tLy.bImpTx = False

        try
            '// get a file to open
            Dim fdlg As Windows.Forms.OpenFileDialog = _
                New Windows.Forms.OpenFileDialog()
            
            fdlg.Title = CMain._T(tx.SELFILE)
            fdlg.FilterIndex = 1
            fdlg.Filter = CMain._T(tx.EXCFILES) & " (*.xls)|*.xls|" & _
                          CMain._T(tx.ALLFILES) & " (*.*)|*.*"
            fdlg.RestoreDirectory = False
            fdlg.FileName = Stgs.sExclImp
        LoopOpen:
            If fdlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Stgs.sExclImp = fdlg.FileName
            Else
                Exit Try
            End If
            
            '// open the worksheet
            ExcelWorkbook = New XLW(fdlg.FileName)
            If (ExcelWorkbook.ErrSts <> XLW.ERR.OK) Then
                if MsgBox(CMain._T(TX.ASKERRWRKB),MsgBoxStyle.YesNo,CMain._T(TX.ASKQ)) = MsgBoxResult.Yes Then
                    GoTo LoopOpen
                End If
                Exit Try
            End If
            
            '// get the sheet list
            Dim sArySht() As String = Nothing
            Dim iActive As Integer
            if ExcelWorkbook.GetSheetList(sArySht, iActive) = False Then
                CMain.AlertUser(tx.ERRSHLST)
                Exit Try
            End If
            '// ask for the one
            Dim ppo As new PromptKeywordOptions( _
                CMain._T(tx.SHTNAME))
            ppo.AllowNone = False
            For i As Integer = 0 to UBound(sArySht)
                ppo.Keywords.Add(sArySht(i))
            Next

            Dim pr As PromptResult = ed.GetKeywords(ppo)
            If pr.Status <> PromptStatus.OK Then
                Exit Try
            End If
            '// attempt to open it
            ExcelSheet = ExcelWorkbook.GetSheet(pr.StringResult)
            If (ExcelSheet Is Nothing) Then
                Dim sKeyLstS as String = ""
                For i As Integer = 0 to UBound(sArySht)
                    sKeyLstS = sKeyLstS & sArySht(i) & vbNewLine
                Next
                CMain.AlertUser(tx.ERRWRKS)
                Exit Try
            End If

            Dim piR As PromptIntegerResult
            Dim pIo As new PromptIntegerOptions( _
                CMain._T(TX.ROWSTART) & ":")
            pIo.DefaultValue = 1
            pIo.AllowNegative = False
            pIo.AllowNone = False
            pIo.AllowZero = False
            pIo.AllowArbitraryInput = False
            pIo.LowerLimit = 1
            piR = ed.GetInteger(pIo)
            If piR.Status <> PromptStatus.OK Then
                Exit Try
            End If
            tLy.lyData.iRowStart = piR.Value
            
            
            pIo.Message = CMain._T(TX.COLSTART) & ":"
            piR = ed.GetInteger(pIo)
            If piR.Status <> PromptStatus.OK Then
                Exit Try
            End If
            tLy.lyData.iColStart = piR.Value
                

            pIo.Message = CMain._T(TX.ROWCNT) & ":"
            piR = ed.GetInteger(pIo)
            If piR.Status <> PromptStatus.OK Then
                Exit Try
            End If
            tLy.lyData.iRowCnt = piR.Value


            pIo.Message = CMain._T(TX.COLCNT) & ":"
            piR = ed.GetInteger(pIo)
            If piR.Status <> PromptStatus.OK Then
                Exit Try
            End If
            tLy.lyData.iColCnr = piR.Value

            '// get the layout
            if (ExcelSheet.GetLayOut(tLy.lyData) = False)
                CMain.AlertUser(tx.ERRLAY)
                Exit Try
            End If

            '// get ratio between the points from excel and drawing
            Dim pdr As Autodesk.AutoCAD.EditorInput.PromptDoubleResult
            Dim pdo As Autodesk.AutoCAD.EditorInput.PromptDoubleOptions
            pdo = New PromptDoubleOptions((vbLf & CMain._T(TX.SCALE) & ":"))
            pdo.AppendKeywordsToMessage = True
            pdo.AllowNegative = False
            pdo.AllowZero = False
            pdo.DefaultValue = 1
            pdr = ed.GetDouble(pdo)
            If (pdr.Status <> PromptStatus.OK) Then
                Exit Try
            End If
            tLy.dScale = pdr.Value
            
            '// get the location
			Dim ppto As PromptPointOptions
			Dim ppr As PromptPointResult
			ppto = New PromptPointOptions(vbLf & CMain._T(TX.FPOINT) & ":")
			ppr = ed.GetPoint(ppto)
            ppo.Keywords.Clear()
			If ppr.Status <> PromptStatus.OK Then
                Exit Try
            End If
            tLy.dEast = ppr.Value.X
            tLy.dNorth = ppr.Value.Y

            tLy.sTxSty = "Standard"

            CreateTblFromLay(acDoc,tLy)

		Catch ex As System.Exception
			CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            if ExcelWorkbook isnot Nothing Then
                ExcelSheet = Nothing
                'If ExcelSheet isnot Nothing Then
                'End If
                ExcelWorkbook.Close()
                ExcelWorkbook = Nothing
            End If
            GC.Collect()
            GC.WaitForPendingFinalizers()
		End Try

	End Sub
    '// ===================================================================== '

#End Region



End Class
'//  CLASS    =============================================================== '
'//
'//
'//
'//
'//  FUNCTIONS    ----------------------------------------------------------- '

'//  FUNCTIONS    =========================================================== '
'//
'//
'//
'//
'// ------------------------------------------------------------------------- '
'// ========================================================================= '


